unit VendaAbertaDM;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ZSequence, ZDataset, ZSqlUpdate, MainDM, CondicaoPagamentoDM, DB,
  QueryConditions, DataRecord;

type

  { TVendaAbertaData }

  TVendaAbertaData = class(TMainDataModule)
    ChequeDatasource: TDatasource;
    ChequeZQuery: TZQuery;
    ChequeZQuerydata_vencimento: TDateField;
    ChequeZQueryid_cheque: TLargeintField;
    ChequeZQueryid_cliente: TLargeintField;
    ChequeZQueryid_duplicata_receber: TLargeintField;
    ChequeZQueryid_venda: TLargeintField;
    ChequeZQuerynota: TStringField;
    ChequeZQuerynumero_agencia: TStringField;
    ChequeZQuerynumero_banco: TStringField;
    ChequeZQuerynumero_cheque: TStringField;
    ChequeZQuerynumero_conta: TStringField;
    ChequeZQuerysituacao_cheque: TStringField;
    ChequeZQueryvalor: TFloatField;
    ChequeZSequence: TZSequence;
    ChequeZUpdate: TZUpdateSQL;
    ClienteZQuery: TZQuery;
    ClienteZQuerybairro: TStringField;
    ClienteZQuerycaixa_postal: TStringField;
    ClienteZQuerycep: TStringField;
    ClienteZQuerycomplemento: TStringField;
    ClienteZQuerydesc_cidade: TStringField;
    ClienteZQueryemail: TStringField;
    ClienteZQueryendereco: TStringField;
    ClienteZQueryid_cidade: TLargeintField;
    ClienteZQueryid_cliente: TLargeintField;
    ClienteZQueryid_pessoa: TLargeintField;
    ClienteZQuerynome_pessoa: TStringField;
    ClienteZQuerynota: TStringField;
    ClienteZQuerynumero: TLongintField;
    ClienteZQuerystatus_cliente: TStringField;
    ClienteZQuerytelefone_celular: TStringField;
    ClienteZQuerytelefone_fax: TStringField;
    ClienteZQuerytelefone_fixo: TStringField;
    ClienteZQuerytipo: TStringField;
    ClienteZQueryuf: TStringField;
    CondicaoPagamentoDatasource: TDatasource;
    CondicaoPagamentoZQuery: TZQuery;
    CondicaoPagamentoZQuerydesc_condicao_pagamento: TStringField;
    CondicaoPagamentoZQueryid_condicao_pagamento: TLargeintField;
    CondicaoPagamentoZSequence: TZSequence;
    CondicaoPagamentoZUpdate: TZUpdateSQL;
    CondPagParcelaZQuerydias: TLongintField;
    CondPagParcelaZQueryid_condicao_pagamento: TLargeintField;
    CondPagParcelaZQueryparcela: TLargeintField;
    CondPagParcelaZQueryporcentagem: TFloatField;
    ContaDatasource: TDatasource;
    ContaZQuery: TZQuery;
    ContaZQuerydesc_conta: TStringField;
    ContaZQueryid_conta: TLargeintField;
    ContaZQuerynota: TStringField;
    ContaZQuerynumero_agencia: TStringField;
    ContaZQuerynumero_banco: TStringField;
    ContaZQuerynumero_conta: TStringField;
    ContaZQueryvalor: TFloatField;
    VendaAbertaItensZQuerysigla_unidade: TStringField;
    VendaAbertaZQueryid_garcon: TLargeintField;
    VendaAbertaZQueryid_mesa: TLargeintField;
    VendaItensDatasource: TDatasource;
    VendaItensZQuery: TZQuery;
    VendaAbertaItensZQueryTotal1: TFloatField;
    VendaItensZQuerycodigo_barra: TStringField;
    VendaItensZQuerydesconto: TFloatField;
    VendaItensZQuerydesc_produto: TStringField;
    VendaItensZQueryid_produto: TLargeintField;
    VendaItensZQueryid_venda: TLargeintField;
    VendaItensZQueryid_venda_produto: TLargeintField;
    VendaItensZQueryquantidade: TFloatField;
    VendaItensZQueryvalor: TFloatField;
    VendaItensZUpdate: TZUpdateSQL;
    VendaDatasource: TDatasource;
    VendaAbertaItensDatasource: TDatasource;
    DuplicataReceberDatasource: TDatasource;
    DuplicataReceberZQuery: TZQuery;
    DuplicataReceberZQueryacrescimo: TFloatField;
    DuplicataReceberZQuerydata_pagamento: TDateField;
    DuplicataReceberZQuerydata_vencimento: TDateField;
    DuplicataReceberZQuerydesconto: TFloatField;
    DuplicataReceberZQueryid_caixa: TLargeintField;
    DuplicataReceberZQueryid_cliente: TLargeintField;
    DuplicataReceberZQueryid_duplicata_receber: TLargeintField;
    DuplicataReceberZQueryid_venda: TLargeintField;
    DuplicataReceberZQuerynota: TStringField;
    DuplicataReceberZQueryparcela: TLargeintField;
    DuplicataReceberZQuerystatus: TStringField;
    DuplicataReceberZQueryvalor: TFloatField;
    DuplicataReceberZQueryvalor_pago: TFloatField;
    DuplicataReceberZSequence: TZSequence;
    DuplicataReceberZUpdate: TZUpdateSQL;
    ProdutoDatasource: TDatasource;
    ProdutoZQuery: TZQuery;
    ProdutoZQuerycodigo_barra: TStringField;
    ProdutoZQuerycusto: TFloatField;
    ProdutoZQuerydesconto: TFloatField;
    ProdutoZQuerydesc_produto: TStringField;
    ProdutoZQueryid_grupo: TLargeintField;
    ProdutoZQueryid_marca: TLargeintField;
    ProdutoZQueryid_produto: TLargeintField;
    ProdutoZQuerynota: TStringField;
    ProdutoZQueryquantidade: TFloatField;
    ProdutoZQuerysigla_unidade: TStringField;
    ProdutoZQueryvalor: TFloatField;
    ProdutoZSequence: TZSequence;
    ProdutoZUpdate: TZUpdateSQL;
    VendaAbertaItensZQuerycodigo_barra: TStringField;
    VendaAbertaItensZQuerydesconto: TFloatField;
    VendaAbertaItensZQuerydesc_produto: TStringField;
    VendaAbertaItensZQueryid_produto: TLargeintField;
    VendaAbertaItensZQueryid_venda_aberta: TLargeintField;
    VendaAbertaItensZQueryid_venda_aberta_produto: TLargeintField;
    VendaAbertaItensZQueryquantidade: TFloatField;
    VendaAbertaItensZQueryTotal: TFloatField;
    VendaAbertaItensZQueryvalor: TFloatField;
    VendaCaixaDatasource: TDatasource;
    VendaCaixaZQuery: TZQuery;
    VendaCaixaZQuerydesconto: TFloatField;
    VendaCaixaZQueryid_caixa: TLargeintField;
    VendaCaixaZQueryid_usuario: TLargeintField;
    VendaCaixaZQueryid_venda: TLargeintField;
    VendaCaixaZQuerysigla_forma_pagamento: TStringField;
    VendaCaixaZQuerytipo_cartao: TStringField;
    VendaCaixaZQueryvalor: TFloatField;
    VendaCaixaZUpdate: TZUpdateSQL;
    VendaAbertaDatasource: TDatasource;
    VendaAbertaZQueryid_venda_aberta: TLargeintField;
    VendaAbertaZQueryvalor: TFloatField;
    VendaAbertaZSequence: TZSequence;
    VendaAbertaZQuery: TZQuery;
    VendaAbertaZUpdate: TZUpdateSQL;
    AuxiliarZQuery: TZQuery;
    VendaAbertaItensZQuery: TZQuery;
    VendaAbertaItensZSequence: TZSequence;
    VendaAbertaItensZUpdate: TZUpdateSQL;
    VendaZQuery: TZQuery;
    VendaZQuerydata: TDateField;
    VendaZQuerydesconto: TFloatField;
    VendaZQueryhora: TTimeField;
    VendaZQueryid_cliente: TLargeintField;
    VendaZQueryid_condicao_pagamento: TLargeintField;
    VendaZQueryid_garcon: TLargeintField;
    VendaZQueryid_mesa: TLargeintField;
    VendaZQueryid_usuario: TLargeintField;
    VendaZQueryid_venda: TLargeintField;
    VendaZQuerynome_pessoa: TStringField;
    VendaZQuerysigla_forma_pagamento: TStringField;
    VendaZQuerystatus_cliente: TStringField;
    VendaZQueryvalor: TFloatField;
    VendaZQueryvalor_total: TFloatField;
    VendaZUpdate: TZUpdateSQL;
    procedure DataModuleCreate(Sender: TObject);
    /// Abre o DataSet
    procedure OpenDataSet(); override;
    /// Fecha o DataSet
    procedure CloseDataSet(); override;
    /// Realiza busca
    /// @param(Condicoes são as condições para a busca)
    /// @param(Tabela é a tabela no banco de dados)
    procedure Search(Condicoes: TQueryConditions; Tabela: string); override;
    procedure VendaItensAbertaZQueryCalcFields(DataSet: TDataSet);
    procedure PagamentoVenda(IDUsuario: integer);
    function VerificaCaixaAberto(): string;
    procedure VendaAdicionaProduto(CodigoBarra: string; Quantidade: real;
      Desconto: real);
    procedure VendaRemoveProduto();
    procedure GeraDuplicataReceber(IDVenda: integer; Data: TDate;
      IDCliente: integer; CondicaoPagamento: integer; Total: real;
      IDCaixa: integer; SiglaPagamento: string);
    procedure GeraCheques(IDVenda: integer; IDCliente: integer);
    procedure InsereVenda(IdVenda: integer; Valor: real);
    procedure FechaPagamentoDinheiro(IDCliente: integer; Desconto: real);
    procedure FechaPagamentoCheque(IDCliente: integer; Desconto: real;
      FormaPagamento: string);
    procedure FechaPagamentoCartao(IDCliente: integer; Desconto: real;
      FormaPagamento: string);
    procedure FechaPagamentoPrazo(IDCliente: integer; FormaPagamento: string;
      Acrescimo: real);
    procedure FechaPagamentoTransferencia(IDCliente: integer;
      Desconto: real; FormaPagamento: string);
    procedure FechaPagamentoBoleto(IDCliente: integer; Desconto: real;
      FormaPagamento: string);
    function BuscaProduto(CodigoBarra: string): TDataRecord;
    function BuscaData(): string;
    function BuscaDataHora(): string;
    procedure CancelaPagamentoVenda();
    procedure InsereVendaCaixa(IDCaixa: string; IDVenda: string;
      Valor: string; SiglaPag: string; IDUsuario: integer);
    procedure Imprimir();
    procedure LimpaTabelasChequePrazo();
    function VerificaSeSistemaRestaurante(): boolean;
    function BuscaVendasMesa(IDMesa: string): boolean;
    function VerificaStatusMesa(IDMesa: string): boolean;
    function BuscaIDVendaMesa(IDMesa: string): string;
    function BuscaVendasControleMesa(DescMesa: string): boolean;
    function BuscaIDMesa(DescMesa: string): string;
    procedure LimpaValoresVenda();
    procedure AtualizaSaldo(IDCaixa: string; Total: string);
    procedure AtualizaMovConta(Valor: string; IDUsuario: Integer;IDCaixa:string);
  end;

var
  VendaAbertaData: TVendaAbertaData;

//! verificar se mesmo em mestre-detalhe os registra estão em memória
implementation

uses ConnectionDM, ProdutoDM, VendaFrDM, DuplicataReceberDM, ChequeDM,
  Printers, ftfont, MesaDM;

{ TVendaAbertaData }

procedure TVendaAbertaData.DataModuleCreate(Sender: TObject);
begin
  MainDataSet := VendaAbertaZQuery;
end;

procedure TVendaAbertaData.OpenDataSet();
begin
  ConnectionData.EmptyQuery(VendaAbertaZQuery, 'venda_aberta');
  VendaAbertaItensZQuery.Open();
end;

procedure TVendaAbertaData.CloseDataSet();
begin
  VendaAbertaItensZQuery.Close();
  VendaAbertaZQuery.Close();
end;

procedure TVendaAbertaData.Search(Condicoes: TQueryConditions; Tabela: string);
begin
  ConnectionData.OpenQueryConditions(VendaAbertaZQuery, Tabela, Condicoes);
end;


procedure TVendaAbertaData.VendaItensAbertaZQueryCalcFields(DataSet: TDataSet);
begin
  VendaAbertaItensZQueryTotal.Value :=
    (VendaAbertaItensZQueryquantidade.AsFloat * VendaAbertaItensZQueryvalor.AsFloat) -
    VendaAbertaItensZQuerydesconto.AsFloat;
end;


//Método que vai iniciar a transação e vai excluir a venda aberta e inserir uma venda fechada
procedure TVendaAbertaData.PagamentoVenda(IDUsuario: integer);
var
  IdVenda: integer;
  Valor: real;
  Garcon: string;
  Mesa: string;
begin
  IdVenda := VendaAbertaZQuery.FieldByName('id_venda_aberta').AsInteger;
  Valor := StrToFloatDef(VendaAbertaZQuery.FieldByName('valor').AsString, 0);
  //Inicia a transação
  with  VendaZQuery do begin
    Open();
    Connection.StartTransaction();
    Insert();
    //Verifica se a venda possui garcon ou mesa
    if VendaAbertaZQuery.FieldByName('id_garcon').AsString <> '' then begin
      FieldByName('id_garcon').AsString :=
        VendaAbertaZQuery.FieldByName('id_garcon').AsString;
    end;
    if VendaAbertaZQuery.FieldByName('id_mesa').AsString <> '' then begin
      FieldByName('id_mesa').AsString :=
        VendaAbertaZQuery.FieldByName('id_mesa').AsString;
    end;
    FieldByName('id_venda').AsInteger := IdVenda;
    FieldByName('valor').AsFloat := Valor;
    FieldByName('id_usuario').AsInteger := IDUsuario;
    Post();
    Edit();
  end;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('INSERT INTO venda_produto(id_venda_produto,id_venda,id_produto,quantidade,valor,desconto) ');
    SQL.Add('SELECT id_venda_aberta_produto,id_venda_aberta,id_produto,quantidade,valor,desconto FROM venda_aberta_produto as va');
    SQL.Add('WHERE va.id_venda_aberta=:id_venda');
    ParamByName('id_venda').AsInteger := IdVenda;
    Open();
    Close();
    SQL.Clear();
    SQL.Add('DELETE FROM venda_aberta_produto');
    SQL.Add('WHERE id_venda_aberta=:id_venda');
    ParamByName('id_venda').AsInteger := IdVenda;
    Open();
    Close();
    SQL.Clear();
    SQL.Add('DELETE FROM venda_aberta');
    SQL.Add('WHERE id_venda_aberta=:id_venda');
    ParamByName('id_venda').AsInteger := IdVenda;
    Open();
  end;
  VendaZQuery.Edit;
end;

function TVendaAbertaData.VerificaCaixaAberto(): string;
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select id_caixa_movimentacao');
    SQL.Add('FROM caixa_movimentacao');
    SQL.Add('where status=:status');
    ParamByName('status').AsString := 'A';
    Open();
    if (RecordCount > 0) then begin
      Result := FieldByName('id_caixa_movimentacao').AsString;
    end else begin
      Result := '';
    end;
  end;
end;

procedure TVendaAbertaData.VendaAdicionaProduto(CodigoBarra: string;
  Quantidade: real; Desconto: real);
var
  Data: TDataRecord;
begin
  //Chama o método Busca Produto utilizando o código de barras
  Data := VendaAbertaData.BuscaProduto(CodigoBarra);
  if Data <> nil then begin
    with VendaAbertaItensZQuery do begin
      Insert();
      FieldByName('id_produto').AsString := Data.getValue('id_produto');
      FieldByName('codigo_barra').AsString := Data.getValue('codigo_barra');
      FieldByName('desc_produto').AsString := Data.getValue('desc_produto');
      FieldByName('valor').AsString := Data.getValue('valor');
      FieldByName('sigla_unidade').AsString := Data.getValue('sigla_unidade');
      FieldByName('quantidade').AsFloat := Quantidade;
      FieldByName('desconto').AsFloat := Desconto * Quantidade;
      Post();
    end;
    with AuxiliarZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('UPDATE produto');
      SQL.Add('SET quantidade = quantidade -:quantidade');
      SQL.Add('WHERE id_produto=:id_produto');
      ParamByName('id_produto').AsString := Data.getValue('id_produto');
      ParamByName('quantidade').AsFloat := Quantidade;
      ExecSQL();
    end;
    //Alterar o valor Total da Venda
    Edit();
    //Fazer o calculo primeiro na tabela
    VendaAbertaZQuery.FieldByName('valor').AsFloat :=
      VendaAbertaZQuery.FieldByName('valor').AsFloat +
      (StrToFloat(Data.getValue('valor')) * Quantidade) - (Desconto * Quantidade);
    Post();
  end else begin
    ShowMessage('Produto Inexistente!');
  end;
end;

procedure TVendaAbertaData.VendaRemoveProduto();
begin
  if not (VendaAbertaItensZQuery.BOF) and not (VendaAbertaItensZQuery.EOF) then begin
    Edit();
    //Fazer o calculo primeiro na tabela
    VendaAbertaZQuery.FieldByName('valor').AsFloat :=
      VendaAbertaZQuery.FieldByName('valor').AsFloat -
      ((VendaAbertaItensZQuery.FieldByName('valor').AsFloat *
      VendaAbertaItensZQuery.FieldByName('quantidade').AsFloat) -
      VendaAbertaItensZQuery.FieldByName('desconto').AsFloat);
    Post();
    VendaAbertaItensZQuery.Delete();
  end;
end;

procedure TVendaAbertaData.GeraDuplicataReceber(IDVenda: integer;
  Data: TDate; IDCliente: integer; CondicaoPagamento: integer; Total: real;
  IDCaixa: integer; SiglaPagamento: string);
begin
  //Primeiro deleta alguma duplicata se já existir para esta venda
  with DuplicataReceberZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('DELETE FROM duplicata_receber where id_venda=:id_venda');
    ParamByName('id_venda').AsInteger := IDVenda;
    ExecSQL();
    if SiglaPagamento = 'C' then begin
      Close();
      SQL.Clear();
      SQL.Add('DELETE FROM cheque where id_venda=:id_venda');
      ParamByName('id_venda').AsInteger := IDVenda;
      ExecSQL();
    end;
    //OBS: Vai deletar os cheque pelo motivo do cliente primeiro gerar os cheques e
    //depois muda para somente a prazo
    Close();
    SQL.Clear();
    //Se a forma de Pagamento for Cheque
    if SiglaPagamento = 'C' then begin
      SQL.Add(
        'INSERT INTO duplicata_receber(id_venda,data_vencimento,data_pagamento,id_cliente,valor,valor_pago,parcela,sigla_forma_pagamento)');
      SQL.add(
        'SELECT :id_venda,:data_vencimento+cpp.dias,:data_vencimento,:id_cliente,:valor*cpp.porcentagem/100,:valor*cpp.porcentagem/100,cpp.parcela,:sigla');
      SQL.Add('FROM condicao_pagamento_parcela as cpp');
      SQL.Add('WHERE cpp.id_condicao_pagamento=:id_condicao_pagamento');
      //Se a forma de Pagamento for Prazo ou Cartao ou Transferencia ou Boleto
    end else begin
      SQL.Add(
        'INSERT INTO duplicata_receber(id_venda,data_vencimento,id_cliente,valor,parcela,sigla_forma_pagamento)');
      SQL.add(
        'SELECT :id_venda,:data_vencimento+cpp.dias,:id_cliente,:valor*cpp.porcentagem/100,cpp.parcela,:sigla');
      SQL.Add('FROM condicao_pagamento_parcela as cpp');
      SQL.Add('WHERE cpp.id_condicao_pagamento=:id_condicao_pagamento');
    end;
    ParamByName('id_venda').AsInteger := IDVenda;
    ParamByName('data_vencimento').AsDate := Data;
    ParamByName('id_cliente').AsInteger := IDCliente;
    ParamByName('valor').AsFloat := Total;
    ParamByName('id_condicao_pagamento').AsInteger := CondicaoPagamento;
    ParamByName('sigla').AsString := SiglaPagamento;
    ExecSQL();
    Close();
    SQL.Clear();
    SQL.Add('SELECT * FROM duplicata_receber where id_venda=:id_venda');
    ParamByName('id_venda').AsInteger := IDVenda;
    Open();
    Edit();
  end;
end;

procedure TVendaAbertaData.GeraCheques(IDVenda: integer; IDCliente: integer);
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE duplicata_receber');
    SQL.Add('SET status = :status');
    SQL.Add('WHERE id_venda=:id_venda');
    ParamByName('status').AsString := 'Q';
    ParamByName('id_venda').AsInteger := IdVenda;
    ExecSQL;
  end;
  with ChequeZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('INSERT INTO cheque(id_duplicata_receber,id_cliente,valor,data_vencimento,id_venda) ');
    SQL.Add('SELECT dr.id_duplicata_receber,:id_cliente,dr.valor,dr.data_vencimento,:id_venda FROM duplicata_receber as dr');
    SQL.Add('WHERE dr.id_venda = :id_venda');
    ParamByName('id_venda').AsInteger := IDVenda;
    ParamByName('id_cliente').AsInteger := IDCliente;
    ExecSQL();
    Close();
    SQL.Clear();
    SQL.Add('SELECT * FROM cheque where id_venda=:id_venda');
    ParamByName('id_venda').AsInteger := IDVenda;
    Open();
    Edit();
  end;
end;


procedure TVendaAbertaData.InsereVenda(IdVenda: integer; Valor: real);
begin
  with VendaZQuery do begin
    Open();
    Insert();
    FieldByName('id_venda').AsInteger := IdVenda;
    FieldByName('valor').AsFloat := Valor;
    Post();
  end;
end;

//Fecha a Venda com Pagamento em Dinheiro
procedure TVendaAbertaData.FechaPagamentoDinheiro(IDCliente: integer; Desconto: real);
var
  IdVenda: integer;
begin
  IdVenda := VendaZQuery.FieldByName('id_venda').AsInteger;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE VENDA');
    SQL.Add('SET id_cliente = :id_cliente, desconto=:desconto, valor_total=valor - :desconto, hora=current_time');
    SQL.Add('WHERE id_venda=:id_venda');
    ParamByName('id_cliente').AsInteger := IDCliente;
    ParamByName('desconto').AsFloat := Desconto;
    ParamByName('id_venda').AsInteger := IdVenda;
    Open();
  end;
  VendaZQuery.Connection.Commit();
  VendaAbertaZQuery.Refresh();
  MainDataSet := VendaAbertaZQuery;
end;

procedure TVendaAbertaData.FechaPagamentoCheque(IDCliente: integer;
  Desconto: real; FormaPagamento: string);
var
  IdVenda: integer;
begin
  IdVenda := VendaZQuery.FieldByName('id_venda').AsInteger;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE VENDA');
    SQL.Add('SET id_cliente = :id_cliente, desconto=:desconto, valor_total=valor - :desconto, sigla_forma_pagamento=:sigla_pagamento, hora=current_time');
    SQL.Add('WHERE id_venda=:id_venda');
    ParamByName('id_cliente').AsInteger := IDCliente;
    ParamByName('desconto').AsFloat := Desconto;
    ParamByName('id_venda').AsInteger := IdVenda;
    ParamByName('sigla_pagamento').AsString := FormaPagamento;
    Open();
  end;
  VendaZQuery.Connection.Commit();
  VendaAbertaZQuery.Refresh();
  MainDataSet := VendaAbertaZQuery;
end;

procedure TVendaAbertaData.FechaPagamentoCartao(IDCliente: integer;
  Desconto: real; FormaPagamento: string);
var
  IdVenda: integer;
begin
  IdVenda := VendaZQuery.FieldByName('id_venda').AsInteger;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE VENDA');
    SQL.Add('SET id_cliente =:id_cliente, desconto=:desconto, valor_total=valor - :desconto, sigla_forma_pagamento=:sigla_pagamento, hora=current_time');
    SQL.Add('WHERE id_venda=:id_venda');
    ParamByName('id_cliente').AsInteger := IDCliente;
    ParamByName('desconto').AsFloat := Desconto;
    ParamByName('id_venda').AsInteger := IdVenda;
    ParamByName('sigla_pagamento').AsString := FormaPagamento;
    Open();
  end;
  VendaZQuery.Connection.Commit();
  VendaAbertaZQuery.Refresh();
  MainDataSet := VendaAbertaZQuery;
end;

procedure TVendaAbertaData.FechaPagamentoPrazo(IDCliente: integer;
  FormaPagamento: string; Acrescimo: real);
var
  IdVenda: integer;
begin
  IdVenda := VendaZQuery.FieldByName('id_venda').AsInteger;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE VENDA');
    SQL.Add('SET id_cliente =:id_cliente, valor_total=valor, sigla_forma_pagamento=:sigla_pagamento, hora=current_time, acrescimo=:acre');
    SQL.Add('WHERE id_venda=:id_venda');
    ParamByName('id_cliente').AsInteger := IDCliente;
    ParamByName('id_venda').AsInteger := IdVenda;
    ParamByName('sigla_pagamento').AsString := FormaPagamento;
    ParamByName('acre').AsFloat := Acrescimo;
    Open();
  end;
  VendaZQuery.Connection.Commit();
  VendaAbertaZQuery.Refresh();
  MainDataSet := VendaAbertaZQuery;
end;

procedure TVendaAbertaData.FechaPagamentoTransferencia(IDCliente: integer;
  Desconto: real; FormaPagamento: string);
var
  IdVenda: integer;
begin
  IdVenda := VendaZQuery.FieldByName('id_venda').AsInteger;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE VENDA');
    SQL.Add('SET id_cliente =:id_cliente, desconto=:desconto, valor_total=valor - :desconto, sigla_forma_pagamento=:sigla_pagamento, hora=current_time');
    SQL.Add('WHERE id_venda=:id_venda');
    ParamByName('id_cliente').AsInteger := IDCliente;
    ParamByName('desconto').AsFloat := Desconto;
    ParamByName('id_venda').AsInteger := IdVenda;
    ParamByName('sigla_pagamento').AsString := FormaPagamento;
    Open();
  end;
  VendaZQuery.Connection.Commit();
  VendaAbertaZQuery.Refresh();
  MainDataSet := VendaAbertaZQuery;
end;

procedure TVendaAbertaData.FechaPagamentoBoleto(IDCliente: integer;
  Desconto: real; FormaPagamento: string);
var
  IdVenda: integer;
begin
  IdVenda := VendaZQuery.FieldByName('id_venda').AsInteger;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE VENDA');
    SQL.Add('SET id_cliente =:id_cliente, desconto=:desconto, valor_total=valor - :desconto, sigla_forma_pagamento=:sigla_pagamento, hora=current_time');
    SQL.Add('WHERE id_venda=:id_venda');
    ParamByName('id_cliente').AsInteger := IDCliente;
    ParamByName('desconto').AsFloat := Desconto;
    ParamByName('id_venda').AsInteger := IdVenda;
    ParamByName('sigla_pagamento').AsString := FormaPagamento;
    Open();
  end;
  VendaZQuery.Connection.Commit();
  VendaAbertaZQuery.Refresh();
  MainDataSet := VendaAbertaZQuery;
end;

function TVendaAbertaData.BuscaProduto(CodigoBarra: string): TDataRecord;
var
  Data: TDataRecord;
begin
  //Data := nil;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * FROM produto ');
    SQL.Add('WHERE codigo_barra=:codigo_barra');
    ParamByName('codigo_barra').AsString := CodigoBarra;
    Open();
    if RecordCount > 0 then begin
      Data := TDataRecord.Create;
      Data.ReadFromDataSet(AuxiliarZQuery);
      Result := Data;
    end else begin
      Result := nil;
    end;
  end;
end;

function TVendaAbertaData.BuscaData(): string;
var
  Data: string;
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT current_date as date');
    Open();
    Data := FieldByName('date').AsString;
    Result := Data;
  end;
end;

function TVendaAbertaData.BuscaDataHora(): string;
var
  Data: string;
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT current_timestamp as date');
    Open();
    Data := FieldByName('date').AsString;
    Result := Data;
  end;
end;

procedure TVendaAbertaData.CancelaPagamentoVenda();
begin
  //VendaAbertaZQuery.Connection.Rollback();
  VendaZQuery.Connection.Rollback();
  MainDataSet := VendaAbertaZQuery;
  VendaAbertaZQuery.Refresh();
end;

procedure TVendaAbertaData.InsereVendaCaixa(IDCaixa: string; IDVenda: string;
  Valor: string; SiglaPag: string; IDUsuario: integer);
begin
  with VendaCaixaZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('INSERT INTO caixa_venda(id_caixa_movimentacao,id_venda,valor,sigla_forma_pagamento,id_usuario)');
    SQL.Add('VALUES (:id_caixa_movimentacao,:id_venda,:valor,:sigla_forma_pagamento,:id_usuario);');
    ParamByName('id_caixa_movimentacao').AsString := IDCaixa;
    ParamByName('id_venda').AsString := IDVenda;
    ParamByName('valor').AsString := Valor;
    ParamByName('sigla_forma_pagamento').AsString := SiglaPag;
    ParamByName('id_usuario').AsInteger := IDUsuario;
    Open();
  end;
end;

//String
{ [%s]=> [This is a string]
      [%0:s]=> [This is a string]
    [%0:18s]=> [  This is a string]
   [%0:-18s]=> [This is a string  ]
 [%0:18.12s]=> [      This is a st]
    [%-*.*s]=> [This is a st      ]

    Fmt:='[%s]';S:=Format(fmt,['This is a string']);
    fmt:='[%0:s]';s:=Format(fmt,['This is a string']);
    fmt:='[%0:18s]';s:=Format(fmt,['This is a string']);
    fmt:='[%0:-18s]';s:=Format(fmt,['This is a string']);
    fmt:='[%0:18.12s]';s:=Format(fmt,['This is a string']);
    fmt:='[%-*.*s]';s:=Format(fmt,[18,12,'This is a string']); }

//Integer
 {        [%d] => [10]
        [%%] => [%]
      [%10d] => [        10]
      [%.4d] => [0010]
    [%10.4d] => [      0010]
      [%0:d] => [10]
    [%0:10d] => [        10]
  [%0:10.4d] => [      0010]
   [%0:-10d] => [10        ]
 [%0:-10.4d] => [0010      ]
    [%-*.*d] => [00010]

Procedure TestInteger;
begin
  Try
    Fmt:='[%d]';S:=Format (Fmt,[10]);
    Fmt:='[%%]';S:=Format (Fmt,[10]);
    Fmt:='[%10d]';S:=Format (Fmt,[10]);
    fmt:='[%.4d]';S:=Format (fmt,[10]);
    Fmt:='[%10.4d]';S:=Format (Fmt,[10]);
    Fmt:='[%0:d]';S:=Format (Fmt,[10]);
    Fmt:='[%0:10d]';S:=Format (Fmt,[10]);
    Fmt:='[%0:10.4d]';S:=Format (Fmt,[10]);
    Fmt:='[%0:-10d]';S:=Format (Fmt,[10]);
    Fmt:='[%0:-10.4d]';S:=Format (fmt,[10]);
    Fmt:='[%-*.*d]';S:=Format (fmt,[4,5,10]);}

procedure TVendaAbertaData.Imprimir();
var
  Msg, sigla, fmt, S, linha, Desc, Prod, Val, codigo, quant, Vlr,
  Desconto, total: string;
  I, W: integer;
  Valor: string;
  teste: string;
begin
  linha := '---------------------------------------------';
  fmt := '%0:43.43s';
  linha := Format(fmt, [linha]);
  with VendaZQuery do begin
    //Dados da Empresa
    Msg := 'Supermercado ?????' + LineEnding;
    Msg := Msg + 'Rua Alzira Torres, ?? Lava pés' + LineEnding;
    //Dados da Venda
    Msg := Msg + 'Venda:' + FieldByName('id_venda').AsString + '-' +
      FieldByName('data').AsString + LineEnding;
    //Dados do Cliente
    //Formato para Tamanho especifico do nome
    fmt := '%0:-17.17s';
    S := Format(fmt, [FieldByName('nome_pessoa').AsString]);
    Msg := Msg + 'Cliente: ' + FieldByName('id_cliente').AsString +
      ' ' + S + LineEnding;
    Msg := Msg + LineEnding;
  end;
  //Produtos
  fmt := '%0:-20s';
  Desc := Format(fmt, ['DESCRIÇÃO']);
  Msg := Msg + 'PRODUTOS:' + LineEnding;
  Msg := Msg + 'CÓD  ' + Desc + ' ' + 'QTD UN(R$) DC VL(R$)' + LineEnding;
  Msg := Msg + linha + LineEnding;

  with VendaAbertaItensZQuery do begin
    for I := 1 to VendaAbertaItensZQuery.RecordCount do begin
      VendaAbertaItensZQuery.RecNo := I;
      fmt := '%0:-17.17s';
      Prod := Format(fmt, [FieldByName('desc_produto').AsString]);
      Valor := FloatToStr(FieldByName('quantidade').AsFloat *
        FieldByName('valor').AsFloat - FieldByName('desconto').AsFloat);
      fmt := '%.4d';
      codigo := Format(fmt, [FieldByName('id_produto').AsInteger]);
      fmt := '%0:4s';
      quant := Format(fmt, [FieldByName('quantidade').AsString]);
      fmt := '%0:4s';
      Vlr := Format(fmt, [FieldByName('valor').AsString]);
      fmt := '%0:4s';
      Desconto := Format(fmt, ['-' + FieldByName('desconto').AsString]);
      Valor := Format(fmt, [Valor]);
      Msg := Msg + codigo + ' ' + Prod + ' ' + quant + ' ' + Vlr +
        ' ' + Desconto + ' ' + Valor + LineEnding;
    end;
  end;
  Msg := Msg + linha + LineEnding;
  with VendaZQuery do begin
    fmt := '%0:30s';
    Val := Format(fmt, [FieldByName('valor').AsString]);
    Msg := Msg + 'SUBTOTAL R$' + Val + LineEnding;
    Val := Format(fmt, ['-' + FieldByName('desconto').AsString]);
    Msg := Msg + 'DESCONTO   ' + Val + LineEnding;
    Val := Format(fmt, [FloatToStr(FieldByName('valor').AsFloat -
      FieldByName('desconto').AsFloat)]);
    Msg := Msg + 'TOTAL R$   ' + Val + LineEnding;
    sigla := FieldByName('sigla_forma_pagamento').AsString;
    if sigla = 'D' then begin
      Msg := Msg + 'DINHEIRO' + LineEnding;
    end else if sigla = 'T' then begin
      Msg := Msg + 'CARTÃO' + LineEnding;
    end else if sigla = 'C' then begin
      Msg := Msg + 'CHEQUE' + LineEnding;
    end else begin
      Msg := Msg + 'PRAZO' + LineEnding;
    end;
    Msg := Msg + 'AGRADECEMOS A PREFERENCIA' + LineEnding;
    Msg := Msg + 'VOLTE SEMPRE';

    //  Printer.Canvas.Font.Size:=32;
    Printer.RawMode := True;
    Printer.BeginDoc;
    W := 0;
    Printer.Write(msg[1], Length(msg), W);
    Printer.EndDoc;
  end;
end;

procedure TVendaAbertaData.LimpaTabelasChequePrazo;
begin
  with ChequeZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * from cheque limit 0');
    Open();
  end;
  with DuplicataReceberZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * from duplicata_receber limit 0');
    Open();
  end;
end;

function TVendaAbertaData.VerificaSeSistemaRestaurante: boolean;
begin
  //Verifica nas configurações se é um sitema para Restaurante
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT valor from configuracao where desc_configuracao=:desc');
    ParamByName('desc').AsString := 'SISTEMA PARA RESTAURANTE';
    Open();
    if RecordCount > 0 then begin
      if FieldByName('valor').AsString = 'S' then begin
        Result := True;
      end else begin
        Result := False;
      end;
    end else begin
      Result := False;
    end;
  end;
end;

//Busca as vendas para uma mesa específica
function TVendaAbertaData.BuscaVendasMesa(IDMesa: string): boolean;
var
  Verifica: boolean;
  IDVendaAberta: string;
begin
  //Verifica se a mesa está livre
  Verifica := VerificaStatusMesa(IDMesa);
  if Verifica = True then begin
    Result := False;
  end else begin
    //Busca o id da venda daquela mesa específica
    IDVendaAberta := BuscaIDVendaMesa(IDMesa);
    if IDVendaAberta = 'N' then begin
      Result := False;
    end else begin
      //Seleciona a venda e itens da venda daquela mesa
      with VendaAbertaZQuery do begin
        Close();
        SQL.Clear();
        SQL.Add(
          'SELECT g.apelido, m.desc_mesa, va.* from venda_aberta as va, garcon as g, mesa as m');
        SQL.Add('where id_venda_aberta=:id_venda_aberta AND g.id_garcon=va.id_garcon');
        SQL.Add('AND m.id_mesa=va.id_mesa');
        ParamByName('id_venda_aberta').AsString := IDVendaAberta;
        Open();
      end;
      with VendaAbertaItensZQuery do begin
        Close();
        SQL.Clear();
        SQL.Add(
          'SELECT p.desc_produto, p.codigo_barra, va.* from venda_aberta_produto as va, produto as p');
        SQL.Add('where id_venda_aberta=:id_venda_aberta AND p.id_produto = va.id_produto');
        ParamByName('id_venda_aberta').AsString := IDVendaAberta;
        Open();
      end;
      Result := True;
    end;
  end;
end;

//Verifica se a mesa está livre
function TVendaAbertaData.VerificaStatusMesa(IDMesa: string): boolean;
var
  I: integer;
begin
  with MesaData.MesaZQuery do begin
    for I := 1 to RecordCount do begin
      RecNo := I;
      if FieldByName('id_mesa').AsString = IDMesa then begin
        if FieldByName('status').AsString = 'L' then begin
          Result := True;
        end else begin
          Result := False;
        end;
      end;
    end;
  end;
end;

//Busca o ID da venda de uma mesa específica
function TVendaAbertaData.BuscaIDVendaMesa(IDMesa: string): string;
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT id_venda_aberta from venda_aberta where id_mesa=:id_mesa');
    ParamByName('id_mesa').AsString := IDMesa;
    Open();
    if RecordCount > 0 then begin
      Result := FieldByName('id_venda_aberta').AsString;
    end else begin
      Result := 'N';
    end;
  end;
end;

//Busca as Vendas de acordo com a Seleção do Controle de MesaFR vindo como parametro a descrição
function TVendaAbertaData.BuscaVendasControleMesa(DescMesa: string): boolean;
var
  I: integer;
  IDMesa: string;
  Verifica: boolean;
begin
  IDMesa := BuscaIDMesa(DescMesa);
  if IDMesa = '' then begin
    Result := False;
  end else begin
    Verifica := BuscaVendasMesa(IDMesa);
    if verifica = True then begin
      Result := True;
    end else begin
      Result := False;
    end;
  end;
end;
//Busca o ID da mesa tendo como parametro a descrição da mesa
function TVendaAbertaData.BuscaIDMesa(DescMesa: string): string;
var
  I: integer;
  IDMesa: string;
begin
  IDMesa := '';
  with MesaData.MesaZQuery do begin
    for I := 1 to RecordCount do begin
      RecNo := I;
      if FieldByName('desc_mesa').AsString = DescMesa then begin
        IDMesa := FieldByName('id_mesa').AsString;
      end;
    end;
  end;
  Result := IDMesa;
end;

procedure TVendaAbertaData.LimpaValoresVenda();
begin
  with VendaAbertaZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * from venda_aberta limit 0');
    Open();
  end;
  with VendaItensZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * from venda_aberta_produto limit 0');
    Open();
  end;
end;

//Atualiza o Saldo da Conta Caixa
procedure TVendaAbertaData.AtualizaSaldo(IDCaixa: string; Total: string);
var
  IDConta: string;
begin
  //Atualizar o Saldo da Conta CAIXA
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT id_conta FROM caixa_movimentacao WHERE id_caixa_movimentacao=:id_caixa');
    ParamByName('id_caixa').AsString := IDCaixa;
    Open();
    IDConta := FieldByName('id_conta').AsString;
  end;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE conta SET saldo=saldo+:valor where id_conta=:id_conta');
    ParamByName('id_conta').AsString := IDConta;
    ParamByName('valor').AsString := Total;
    Open();
  end;
end;

procedure TVendaAbertaData.AtualizaMovConta(Valor: string; IDUsuario: Integer;
  IDCaixa: string);
var
  IDPlanoConta: string;
  IDConta:string;
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT valor FROM configuracao where desc_configuracao=:configuracao');
    ParamByName('configuracao').AsString := 'PLANO_CONTA VENDA';
    Open();
    IDPlanoConta := FieldByName('valor').AsString;
  end;
   with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT id_conta FROM caixa_movimentacao where id_caixa_movimentacao=:id_caixa_movimentacao');
    ParamByName('id_caixa_movimentacao').AsString := IDCaixa;
    Open();
    IDConta := FieldByName('id_conta').AsString;
  end;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('INSERT INTO plano_conta_movimentacao(id_conta,id_plano_conta,id_usuario,valor,id_caixa_movimentacao)');
    SQL.Add('VALUES(:id_conta,:id_plano_conta,:id_usuario,:valor,:id_caixa_movimentacao);');
    ParamByName('id_conta').AsString := IDConta;
    ParamByName('id_plano_conta').AsString := IDPlanoConta;
    ParamByName('id_usuario').AsInteger := IDUsuario;
    ParamByName('valor').AsString := Valor;
    ParamByName('id_caixa_movimentacao').AsString := IDCaixa;
    ExecSQL();
  end;
end;

initialization
  {$I vendaabertadm.lrs}

end.
